使用java imageio 调整图片DPI,例如从72调整为300 - - ITeye博客

创建时间:2019/7/30 11:55
来源:https://lflei.iteye.com/blog/2363690


Java生成图片默认分辨率是72dpi,由于需要打印生成图片,要求图片分辨率至少300dpi,这个问题整了将近一天时间,最终得到解决,感谢网友的分享。在这里记录一下,已备后面使用。以下代码摘抄至https://my.oschina.net/osgit/blog/530283

/**
* 接口设计
*/
public interface ImageDPIProcessor {

    /**
     * 根据文件后缀扩展名判断是否能进行处理
     * 
     * @param fileName
     * @return
     */
    public boolean canHandle(String fileName);

    /**
     * 
     * @param path
     * @param dpi
     *            dot per inch
     * @return
     * @throws IOException
     * @throws MalformedURLException
     */
    public byte[] process(final BufferedImage srcimage, final int dpi) throws Exception;

 

JPEG 处理方式

public class JpegDPIProcessor implements ImageDPIProcessor {

    private String formatName = "jpeg";

    @Override
    public byte[] process(BufferedImage image, int dpi) throws IOException {
        for (Iterator<ImageWriter> iw = ImageIO.getImageWritersByFormatName(formatName); iw.hasNext();) {
            ImageWriter writer = iw.next();

            ImageWriteParam writeParams = writer.getDefaultWriteParam();
            writeParams.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
            //调整图片质量
            writeParams.setCompressionQuality(1f);

            IIOMetadata data = writer.getDefaultImageMetadata(new ImageTypeSpecifier(image), writeParams);
            Element tree = (Element) data.getAsTree("javax_imageio_jpeg_image_1.0");
            Element jfif = (Element) tree.getElementsByTagName("app0JFIF").item(0);
            jfif.setAttribute("Xdensity", dpi + "");
            jfif.setAttribute("Ydensity", dpi + "");
            jfif.setAttribute("resUnits""1"); // density is dots per inch

            ByteArrayOutputStream out = new ByteArrayOutputStream();
            ImageOutputStream stream = null;
            try {
                stream = ImageIO.createImageOutputStream(out);
                writer.setOutput(stream);
                writer.write(data, new IIOImage(image, nullnull), writeParams);
            } finally {
                stream.close();
            }

            return out.toByteArray();
        }
        return null;

    }

    @Override
    public boolean canHandle(String fileName) {
        assert fileName != null : "fileName should not be null";

        return fileName.endsWith("jpg") || fileName.endsWith("jpeg") || fileName.endsWith("JPG")
                || fileName.endsWith("JPEG");
    }

}

 

PNG处理方式:

public class PngDPIProcessor implements ImageDPIProcessor {
   //1英寸是2.54里面
    private static final double INCH_2_CM = 2.54d;

    @Override
    public boolean canHandle(String fileName) {
        assert fileName != null : "fileName should not be null";

        return fileName.endsWith("png") || fileName.endsWith("PNG");
    }

    @Override
    public byte[] process(BufferedImage image, int dpi) throws MalformedURLException, IOException {


        for (Iterator<ImageWriter> iw = ImageIO.getImageWritersByFormatName("png"); iw.hasNext();) {
            ImageWriter writer = iw.next();
            ImageWriteParam writeParam = writer.getDefaultWriteParam();
            ImageTypeSpecifier typeSpecifier = ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_INT_RGB);
            IIOMetadata metadata = writer.getDefaultImageMetadata(typeSpecifier, writeParam);
            if (metadata.isReadOnly() || !metadata.isStandardMetadataFormatSupported()) {
                continue;
            }
            ByteArrayOutputStream output = new ByteArrayOutputStream();
            ImageOutputStream stream = null;
            try {
                setDPI(metadata, dpi);
                stream = ImageIO.createImageOutputStream(output);
                writer.setOutput(stream);
                writer.write(metadata, new IIOImage(image, null, metadata), writeParam);
            } finally {
                try {
                    stream.close();
                } catch (IOException e) {
                }
            }
            return output.toByteArray();
        }

        return null;
    }

    private void setDPI(IIOMetadata metadata, int dpi) throws IIOInvalidTreeException {

        // for PMG, it's dots per millimeter
        double dotsPerMilli = 1.0 * dpi / 10 / INCH_2_CM;
        IIOMetadataNode horiz = new IIOMetadataNode("HorizontalPixelSize");
        horiz.setAttribute("value", Double.toString(dotsPerMilli));

        IIOMetadataNode vert = new IIOMetadataNode("VerticalPixelSize");
        vert.setAttribute("value", Double.toString(dotsPerMilli));

        IIOMetadataNode dim = new IIOMetadataNode("Dimension");
        dim.appendChild(horiz);
        dim.appendChild(vert);

        IIOMetadataNode root = new IIOMetadataNode("javax_imageio_1.0");
        root.appendChild(dim);

        metadata.mergeTree("javax_imageio_1.0", root);
    }
主要参考文章:
https://my.oschina.net/osgit/blog/530283
http://stackoverflow.com/questions/321736/how-to-set-dpi-information-in-an-image
分享到:
评论
相关资源推荐
  • 使用java imageio 调整图片DPI,例如从72调整300

    rnJava生成图片默认分辨率是72dpi,由于需要打印生成图片,要求图片分辨率至少300dpi,这个问题整了将近一天时间,最终得到解决,感谢网友的分享。在这里记录一下,已备后面使用。以下代码摘抄至https://my.oschina.net/osgit/blog/530283rn/**rn* 接口设计rn*/rnpublic interface ImageDPIProcessor {rnrn  ...

  • java保存图像,设置其DPI

    import java.awt.*;rnimport java.awt.image.*;rnimport java.io.*;rnimport java.net.*;rnimport javax.imageio.*;rnrnimport java.awt.Graphics;rnimport java.awt.image.BufferedImage;rnimport java.awt.Image;r...

  • 图像DPI调整工具

    简介的图像DPI调整工具,非常好用,操作简单,免安装绿色版!

  • java设置图像dpi

  • JAVAImageIO处理JPG图片

    [code=&quot;java&quot;] Image srcImage = ImageIO.read(srcFile);rn rn // 原始图片大小rn int srcImageWidth = srcImage.getWidth(null);rn int srcImageHeight = srcImage.getHeight(null);rn ...

  • 图片缩放并设置dpi

    这几天遇到个需求,要求缩放图片,但是不能改变图片dpi,用 opencv 不行,于是在网上找,但是找了很久没有找到相关的信息,只有一篇帖子说使用 Gdiplus 可以满足这个需求,遂研究了一下 Gdiplus 的接口,终于找到了 Gdiplus::Bitmap::SetResolution 这个方法,新技能 Get!nn完整的代码如下:nn#pragma comment(lib, &quot;Gdiplu...

  • Python修改保存图片分辨率(dpi)问题

    首先导入 pillow ,下载地址:https://pypi.org/project/Pillow/代码:from PIL import Image as ImagePIL, ImageFont, ImageDrawnfrom StringIO import StringIOnndef test(req):。。。。。。# 保存图片im = ImagePIL.open('/home/uftp/jia...

  • # Android 设置PNG图片的 打印分辨率 dpi (pHYs)

    Android 设置PNG图片的打印分辨率dpi(pHYs)rn1.了解png的原文件数据,头文件IHDR,控制物理密度的pHYs,rnrnrn关于png的头文件IHDR:rnrnrnhttps://blog.csdn.net/satanzw/article/details/38757121rnpng图片都是以固定标识89 50 4E 47 0D 0A 1A 0A开始,然后接着IHDRrn例如一张png从头开始为:...

  • 使用JavaImageIO图片处理实现

    [code=&quot;java&quot;]rnimport java.awt.Graphics2D;rnimport java.awt.Image;rnimport java.awt.RenderingHints;rnimport java.awt.image.BufferedImage;rnimport java.awt.image.ColorModel;rnimport java.io.File;rnimpo...

  • 关于图片dpi的问题

    问题nn最近使用tensorflow中的tf.gfile.FastGFile()函数读取jpg文件,总是出现如下错误,貌似是说文件的格式不是jpg格式。但是我看了图片的属性明明是jpg的格式。nnnn解决nn想起来我原来的图片类型是tiff格式,为了改成jpg格式,曾写过一段代码,但是该代码只是名称上将tiff格式改成了jpg格式,实际图片的存储形式并没有改变。笔者自己也没有深究究竟存储有什么不同...

  • 获取图片DPI

       最近在项目中有个需求:区分拍照图片与扫描图片。找不到什么好的方法,目前感觉可行的方式是通过DPI来区分:nn一般拍照图片DPI是96甚至更低,扫描图片DPI一般是120、150、200、300等更高。nn  但是opencv没有获取DPI相关的函数,遍寻百度,觉得还是GDI+实现起来较好。nn GDI+的头文件和库,在windows系统中是自带的。nn先要引入GDI+的头文件和库nnn#in...

  • 根据屏幕大小及dpi调整缩放和大小

    n n n &amp;lt;script&amp;gt;n//根据屏幕大小及dpi调整缩放和大小n(function() {nvar scale = 1.0;nvar ratio = 1;nif (window.devicePixelRatio &amp;gt;= 2) {nscale *= 0.5;nratio = 2;n}nvar text = '&amp;lt;meta name=&quot;viewp...

  • Java imageio图片处理

  • 使用Windows自带画图工具修改图片大小

    一、打开Windows再带的画图工具n打开方式:nn1、【开始】-【所有程序】-【附件】-【画图】n或者n2、打开运行命令框-输入mspaint-单击确定nnn二、用画图打开要修改大小的图片nn三、修改图片大小n单击左上角【重新调整大小】n有两种调整大小的方式可以选:1、按照百分比缩放;2、设置像素值(例如640*480)调整大小,注意:默认情况下是保持纵横比,可以不勾选,

  • Opencv 显示图片 改变图片分辨率 保存图片 改变图片大小入门操作

    本资源包含一个mfc基于对话框的工程。该工程除了可以用做初步学习opencv的入门级学习资料。也可以作为一个工具(至少我用来做头像了,将一个图片反复缩小就得到了合适大小的了) 此工程能够实现的功能有: ①利用Opencv在mfc控件上显示图片。 ②利用Opencv改变图片的分辨率(默认是缩小为原来一般的分辨率)并显示在mfc对话框一个图片控件中。 ③保存。对话框有一个保存按钮。用于保存更改了分辨率之后的图片。(对于更改了之后的图片。又可以再次执行相同的①②③操作得到缩小1/4分辨率的图片,当然图片大小也缩小了) 关于工程:工程一个两个图片控件。分别用于显示原始图片和更改了分辨率之后的图片。三个按钮。分别对应上面所说的三个功能。

  • 利用ImageIO压缩图片

    http://java-mzd.iteye.com/blog/730504nhttp://blog.csdn.net/10km/article/details/52119508nnn参考上面文章,测试了下 写的很好!

  • Java 识别图片分辨率的问题

    近期做关于识别PDF的项目,里面涉及到提取PDF中的图片,并识别图片的分辨率,对较小分辨率的图片,再生成新的PDF的时候舍弃。n对于提取PDF中的图片信息可以使用PDFBox库,很简单也很灵活(当然也存在bug,我在提取某个PDF文件中图片的时候,发现有一些图片在原文件中根本不存在,还希望来个大神解答一下。。。),废话少说,直接附上代码供大家参考:

  • 读取图像DPI信息的方法

    今天有个项目需要获取图像DPI信息,搜了几篇博客的描述,最终采用GDI+的方法实现,总结实现方法如下:nn0.编程平台:VS2015,语言:C++nn1.下载GDI+包,初始化GDI+环境nn(1)在工程的App类中增加声明信息,主要包括头文件包含,拷贝库文件gdiplus.lib到工程目录,拷贝动态库文件gdiplus.dll到工程输出文件(一般release或debug目录)。或者在工程中编译...

  • 【c++】修改jpg图像的dpi

    opencv处理保存后的图像,会改变其原来的dpi数值先调用读取jpg图片dpi函数,然后opencv保存后,再写入原先的dpi值下面是修改jpg图片dpi函数bool SetResolution(const char* path, int iResolution) n{ n FILE * file = fopen(path,&quot;rb+&quot;);// - 打开图片文件 n if (!file)ret...

  • java使用ImageIo获取图片信息